In typical software programs, data is stored in data structures. Typically, each data structure used to store data is an instance of a particular data type. Many data types can be quite complex. For example, a data type may include numerous subcomponents, where each subcomponent is of a complex data type.
The terminology used to refer to data types, and the subcomponents of data types, varies based on the programming environment involved. For example, in some programming environments, data types correspond to object “classes”, and the subcomponents of data types correspond to “attributes”. In other environments, data types correspond to “records” and the subcomponents correspond to “fields”. In other environments, data types correspond to arrays, and the subcomponents correspond to elements of the arrays. For the purpose of explanation, the terms “data type” and/or “class” shall be used to refer to a defined structure for storing data, and the term “attribute” shall be used to refer to a subcomponent of that structure.
An aggregate data type is a data type composed of multiple elements. An aggregate data type may be homogeneous, in that all elements of the aggregate data type may be of the same data type (e.g., an array, a list in a functional language, a string of characters). An aggregate data type may be heterogeneous, in that elements of the aggregate data type may be of different data types (e.g., a structure). In some programming environments, aggregate data types may contain elements that are also aggregate data types (e.g., a list of lists).
The management of memory during the execution of a computer program can have a significant effect on the performance of the computer program. One memory management issue relates to how to allocate memory for instances of aggregate data types. Specifically, storing the attributes of an instance in many relatively small memory segments may hinder performance in systems where memory is abundant. On the other hand, storing the attributes of an instance in few relatively larger memory segments may waste memory, and may also hinder performance in a system where memory is a scarce resource.
Another memory management issue relates to how memory is managed during assignment operations. Some programming environments (e.g., PL/SQL) allow an instance of a subclass to be assigned to a variable that references an instance of a superclass of that subclass. Such an assignment may be referred to as a “widening assignment,” because the total memory required by the instance of the subclass will be greater than the total memory required by the instance of the superclass. When memory is allocated for the instance of the subclass, some approach is taken for determining a location at which that memory will be allocated.
Using a total reallocation approach, a memory manager frees all of the memory allocated to the instance of the superclass and allocates for the instance of the subclass a potentially different segment of memory without regard to the location of the memory that was allocated to the superclass. The rationale for such total reallocation is that additional memory contiguous with memory allocated to the instance of the superclass may not be available for allocation to the not-inherited attributes of the instance of the subclass.
Using the total reallocation approach can cause the address of an attribute of the instance referenced by the variable to change, even when that attribute is common to both the superclass and the subclass. In circumstances when the address of the attribute was cached prior to the change, such a change causes the cached address to become invalid, reducing the efficiency obtained from caching.